React Suspense Ressource-deduplikering: Forebyggelse af dobbelte anmodninger | MLOG | MLOG

Nu kontrollerer UserResource, om en ressource allerede findes i cache. Hvis den gør, returneres den cachede ressource. Ellers startes en ny anmodning, og det resulterende promise gemmes i cachen. Dette sikrer, at der kun foretages én anmodning for hvert unikt userId.

2. Brug af et dedikeret caching-bibliotek (f.eks. `lru-cache`)

For mere komplekse caching-scenarier kan du overveje at bruge et dedikeret caching-bibliotek som lru-cache eller lignende. Disse biblioteker tilbyder funktioner som cache-fjernelse baseret på Least Recently Used (LRU) eller andre politikker, hvilket kan være afgørende for at styre hukommelsesforbruget, især når man håndterer et stort antal ressourcer.

Installer først biblioteket:

            
npm install lru-cache

            

Integrer det derefter i din UserResource:

            
import React, { Suspense } from 'react';
import LRUCache from 'lru-cache';

const fetchUser = (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Simuler netværksanmodning
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id: userId, name: `User ${userId}`, email: `user${userId}@example.com` });
    }, 1000); // Simuler netværksforsinkelse
  });
};

const cache = new LRUCache({
  max: 100, // Maksimalt antal elementer i cachen
  ttl: 60000, // Levetid i millisekunder (1 minut)
});

const UserResource = (userId) => {
  if (!cache.has(userId)) {
    let promise = null;
    let status = 'pending'; // afventer, succes, fejl
    let result;

    const suspender = fetchUser(userId).then(
      (r) => {
        status = 'success';
        result = r;
        cache.set(userId, {
          read() {
            return result;
          },
        });
      },
      (e) => {
        status = 'error';
        result = e;
        cache.set(userId, {
          read() {
            throw result;
          },
        });
      }
    );

    cache.set(userId, {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        }
    });
  }

  return cache.get(userId);
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Denne tilgang giver mere kontrol over cachens størrelse og udløbspolitik.

3. Request Coalescing med biblioteker som `axios-extensions`

Biblioteker som axios-extensions tilbyder mere avancerede funktioner såsom request coalescing. Request coalescing kombinerer flere identiske anmodninger til en enkelt anmodning, hvilket yderligere optimerer netværksforbruget. Dette er især nyttigt i scenarier, hvor anmodninger startes meget tæt på hinanden i tid.

Installer først biblioteket:

            
npm install axios axios-extensions

            

Konfigurer derefter Axios med den cache-adapter, der leveres af axios-extensions.

Eksempel med brug af `axios-extensions` og oprettelse af en ressource:

            
import React, { Suspense } from 'react';
import axios from 'axios';
import { cacheAdapterEnhancer, throttleAdapterEnhancer } from 'axios-extensions';

const instance = axios.create({
  baseURL: 'https://api.example.com', // Erstat med dit API-endepunkt
  adapter: cacheAdapterEnhancer(axios.defaults.adapter, { enabledByDefault: true }),
});

const fetchUser = async (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Simuler netværksanmodning
  const response = await instance.get(`/users/${userId}`);
  return response.data;
};


const UserResource = (userId) => {
    let promise = null;
    let status = 'pending'; // afventer, succes, fejl
    let result;

    const suspender = fetchUser(userId).then(
        (r) => {
            status = 'success';
            result = r;
        },
        (e) => {
            status = 'error';
            result = e;
        }
    );

    return {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        },
    };
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Dette konfigurerer Axios til at bruge en cache-adapter, der automatisk cacher svar baseret på anmodningskonfigurationen. Funktionen cacheAdapterEnhancer giver muligheder for at konfigurere cachen, såsom at indstille en maksimal cachestørrelse eller udløbstid. throttleAdapterEnhancer kan også bruges til at begrænse antallet af anmodninger til serveren inden for en bestemt tidsperiode, hvilket yderligere optimerer ydeevnen.

Bedste praksis for ressource-deduplikering

Globale overvejelser for datahentning og deduplikering

Når man designer strategier for datahentning til et globalt publikum, spiller flere faktorer ind:

For eksempel kan en rejsebookingside, der henvender sig til et globalt publikum, bruge et CDN til at servere data om fly- og hotel-tilgængelighed fra servere placeret i forskellige regioner. Hjemmesiden ville også bruge en valutaomregnings-API til at vise priser i brugerens lokale valuta og give mulighed for at filtrere søgeresultater baseret på sprogpræferencer.

Konklusion

Ressource-deduplikering er en essentiel optimeringsteknik for React-applikationer, der bruger Suspense. Ved at forhindre dobbelte datahentningsanmodninger kan du markant forbedre ydeevnen, reducere serverbelastningen og forbedre brugeroplevelsen. Uanset om du vælger at implementere en simpel promise-cache eller udnytte mere avancerede biblioteker som lru-cache eller axios-extensions, er nøglen at forstå de underliggende principper og vælge den løsning, der bedst passer til dine specifikke behov. Husk at overveje globale faktorer som CDN'er, lokalisering og tilgængelighed, når du designer dine datahentningsstrategier for et mangfoldigt publikum. Ved at implementere disse bedste praksisser kan du bygge hurtigere, mere effektive og mere brugervenlige React-applikationer.